﻿using Microsoft.Practices.EnterpriseLibrary.Logging;
using System.Collections.Generic;
using System.Threading.Tasks;

namespace Sidvall.Logging.EL
{
    public class Log : Sidvall.Logging.ILog
    {
        #region Public Members

        #region ShouldLog

        public bool ShouldLog(IEnumerable<string> categories, EventType severity)
        {
            var traceEventType = GetTraceEventType(severity);
            var item = new LogEntry()
            {
                Severity = traceEventType,
            };
            if (categories != null)
            {
                foreach (var category in categories)
                    item.Categories.Add(category);
            }
            return LogWriter.ShouldLog(item);
        }

        #endregion
        #region WriteAsync

        public Task WriteAsync(string title, string message, IEnumerable<string> categories, EventType severity, IDictionary<string, string> properties)
        {
            var result = WriteToLog(title, message, categories, severity, properties);
            return Task.FromResult(result);
        }

        #endregion
        #region ToString

        public override string ToString()
        {
            return "Log - EnterpriseLibrary";
        }

        #endregion

        #endregion
        #region Private Members

        private LogWriter LogWriter { get; set; }

        #region GetTraceEventType

        private static System.Diagnostics.TraceEventType GetTraceEventType(EventType severity)
        {
            switch (severity)
            {
                case EventType.Critical:
                    return System.Diagnostics.TraceEventType.Critical;
                case EventType.Error:
                    return System.Diagnostics.TraceEventType.Error;
                case EventType.Warning:
                    return System.Diagnostics.TraceEventType.Warning;
                case EventType.Information:
                    return System.Diagnostics.TraceEventType.Information;
                default:
                    throw new System.ArgumentException(nameof(severity));
            }
        }

        #endregion
        #region WriteToLog

        private bool WriteToLog(string title, string message, IEnumerable<string> categories, EventType severity, IDictionary<string, string> properties)
        {
            Dictionary<string, object> items;

            if (!this.LogWriter.IsLoggingEnabled())
                return false;
            if (categories == null)
                categories = new List<string>();
            var traceEventType = GetTraceEventType(severity);
            if (properties != null)
            {
                items = new Dictionary<string, object>();
                foreach (var property in properties)
                    items.Add(property.Key, property.Value);
            }
            else
            {
                items = null;
            }
            this.LogWriter.Write(message, categories, 1, 1, traceEventType, title, items);
            return true;
        }

        #endregion

        #endregion
        #region Constructors

        public Log()
        {
            var logWriterFactory = new LogWriterFactory();
            this.LogWriter = logWriterFactory.Create();
            Logger.SetLogWriter(this.LogWriter, false);
        }

        #endregion
    }
}
